#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>

using namespace std;

namespace gm
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef T* const_iterator ;
		
		vector(){}

		vector(const vector<T>& v)
		{
			_start = new T[v.capacity()];
			memcpy(_start,v._start,sizeof(T)*v.size());
			_finish = _start + v.size();
			_endofstorage = _start + v.capacity();
		}

		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_endofstorage, v._endofstorage);
		}

		vector<T>& operator = (vector<T> v)
		{
			swap(v);
			return *this;
		}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t old = size();
				T* tmp = new T[n];
				if (_start)
				{
					memcpy(tmp,_start,sizeof(T)*size());
					delete[] _start;
				}
				_start = tmp;
				_finish = _start + old;
				_endofstorage = _start + n;
			}
		}

		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newcapacity);
			}

			*_finish = x;
			++_finish;
		}

		size_t size()
		{
			return _finish - _start;
		}

		int capacity()
		{
			return _endofstorage - _start;
		}

		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _endofstorage = nullptr;
			}
		}

	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _endofstorage = nullptr;
	};



	class string
	{
	public:
		string(const char* str = "")
		{
			_size = strlen(str);
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str,str);
		}

		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}

		string(const string& s)
		{
			string tmp(s._str);
			swap(tmp);
		}

		string& operator = ( string s)
		{
			swap(s);
			return *this;
		}

		void push_back(char ch)
		{
			if (_size == _capacity)
			{
				int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';
		}


		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		const static size_t npos = -1;
	};

	template<class T>
	class shared_ptr
	{
	public:
		//shared_ptr(T* ptr = nullptr)
		//	:_ptr(ptr)
		//	, _use_count(new size_t(0))
		//{}

		shared_ptr(T* ptr)
			:_ptr(ptr)
			, _use_count(new size_t(1))
		{}

		shared_ptr<T>& operator = (const shared_ptr<T>& ptr)
		{
			if (_ptr != ptr._ptr)
			{
				release();
				_ptr = ptr._ptr;
				_use_count = ptr._use_count
				++(*_use_count);
			}
			return *this;
		}

		void release()
		{
			if (--(*_use_count) == 0)
			{
				delete _ptr;
				delete _use_count;
			}
		}

		~shared_ptr()
		{
			release();
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

		T* get() const
		{
			return _ptr;
		}

	private:
		T* _ptr;
		size_t* _use_count;
	};
}


int main()
{
	char arr[] = "hello";
	printf("%d\n", strlen(arr));
	printf("%d\n",sizeof(arr));
	return 0;
}